import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;


public class LanguageGuesser 
  
{
  
  public static void main(String[] args)
  {
    String[] fileNames = {"slovak.txt", "bulgarian.txt", "czech.txt", "danish.txt", 
      "dutch.txt", "english.txt", "estonian.txt", "finnish.txt", "french.txt", 
      "german.txt", "greek.txt", "hungarian.txt", "italian.txt", "latvian.txt",
      "lithuanian.txt", "polish.txt", "portuguese.txt", "romanian.txt", "slovenian.txt",
      "spanish.txt", "swedish.txt"};   
    
    Scanner input = null;
    
    
    System.out.println("Please specify the n for your n-gram: ");
    Scanner keyboard = new Scanner(System.in);
    int n= keyboard.nextInt();
    
    for(String fileName: fileNames)
    {
      //reading the file
      try
      {
        input = new Scanner (new File(fileName), "UTF-8");
      }
      catch(FileNotFoundException e)
      {
        System.out.println("Could not open the file " + fileName);
        System.exit(0);
      }
      input.useDelimiter("\\Z");
      //storing the text as a string and then after removing whitespaces in an array
      String text = input.next();
      text = text.replaceAll("\\s+", " ");
      //the " character turned out to be problematic (was considered as end of input by read buffer) so I had to remove all its occurences
      //text = text.replaceAll("\\p{Punct}", "");
      double textLength= text.length();
      
      System.out.println("The program has just read the " +fileName + " file."  );
//         System.out.println("Please specify the n for your n-gram: ");
//         Scanner keyboard = new Scanner(System.in);
//         int n= keyboard.nextInt();
      List<Map<String, Double>> listOfMaps = new ArrayList<Map<String, Double>>();
      
      for(int i=0; i<n; i++)
      {
        HashMap<String, Double> hashMap = new HashMap<String, Double>();
        listOfMaps.add(i, hashMap);
      }
      //storing the ngrams in hashmaps contained in an arraylist where the index+1 corresponds to the n of the ngram
      double countUnigrams = 0.0;
      int k =1;
      for(int i=0; i<text.length();i++)
      {
        while(k!=n+1)
        {    
          if(i+k<text.length())
          {
            String n1gram = text.substring(i, i+k);
            if(n1gram.length()==1)
              countUnigrams++;
            if(!listOfMaps.get(k-1).containsKey(n1gram))
            {
              listOfMaps.get(k-1).put(n1gram, 1.0);
            }
            else
            {
              double count = listOfMaps.get(k-1).get(n1gram) + 1.0;
              listOfMaps.get(k-1).put(n1gram, count);
            }
            
          }
          k++;
        }
        k=1;
      }
      
      //writing the hashMap to the file
      String outputfileName = "prbs" +fileName;
      PrintWriter outputStream= null;
      try
      {
        outputStream = new PrintWriter(outputfileName);  
      }
      catch(FileNotFoundException e)
      {
        System.out.println("Could not open the file " + fileName);
        System.exit(0);
      }   
      
      for(int i=0; i<listOfMaps.size(); i++)
      {
        
        Set ref = listOfMaps.get(i).keySet();;
        Iterator it = ref.iterator();
        while (it.hasNext())
        {
          String nGramKey = (String)it.next();
          String context= " ";
          int contextIndex = 0;
     
          double prb= 0.0;
          if(nGramKey.length()>1)
          {
            context = nGramKey.substring(0, nGramKey.length()-1);
            contextIndex = i-1;
            //System.out.println("The key " +  nGramKey + " and the context" + context);
            prb = (listOfMaps.get(i).get(nGramKey)-0.5)/ (listOfMaps.get(contextIndex).get(context));
            outputStream.write(nGramKey + "\n" + 
                               prb + "\n"); 
          }
          //if we have a unigram then we divide by the total frequency of the unigrams
          else
          {
            //System.out.println("The key " +  nGramKey + " and the freq" + listOfMaps.get(i).get(nGramKey));
            prb = (listOfMaps.get(i).get(nGramKey)-0.5)/ (countUnigrams);
            outputStream.write(nGramKey + "\n" + 
                               prb + "\n"); 
          }
          
          
          
        }
        
      }
      outputStream.write("end of probabilities");
      outputStream.close();     
      
      System.out.println("Some output for debugging: ");
      for(int i=0; i<listOfMaps.size(); i++)
      {
        Set ref = listOfMaps.get(i).keySet();;
        Iterator it = ref.iterator();
        int count10=0;
        System.out.println("for the n-grams where n equalls: " + (i+1)+
                           " we get the following first entries: ");
        while (it.hasNext()) 
        {
          if (count10==3)
            break;
          String nGramKey = (String)it.next();
          System.out.println("The ngram: " + nGramKey + " and the count: " + 
                             listOfMaps.get(i).get(nGramKey));
          count10++;
        }
      }
    }
  }
  
}
